package com.andaily.ccg.view;

import com.andaily.ccg.infrastructure.PreferencesUtil;
import com.andaily.ccg.infrastructure.SwingUtil;

import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @author Shengzhao Li
 */
public class MainJFrame extends JFrame {


    public MainJFrame() {
        this.initialComponents();
        this.executeEvent();
        this.initialDefaultValues();
        this.showMe();
    }

    private void initialDefaultValues() {
        final String compilerJarPath = PreferencesUtil.getCompilerJarPath();
        this.compileJarTextField.setText(compilerJarPath);
        File file = new File(compilerJarPath);
        if (file.exists()) {
            this.jarFileChooser.setCurrentDirectory(file.getParentFile());
        }

        this.compiledTextField.setText(PreferencesUtil.getCompiledJSPath());

        final String compileJSPath = PreferencesUtil.getCompileJSPath();
        this.fileTextField.setText(compileJSPath);
        file = new File(compileJSPath);
        if (file.exists()) {
            this.fileChooser.setCurrentDirectory(file.getParentFile());
        }
    }

    private void executeEvent() {
        this.executeBtn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                executeBtn.setEnabled(false);
                appendMessage("Starting......");
                EventQueue.invokeLater(new Runnable() {
                    @Override
                    public void run() {
                        boolean checkingSuccess = true;
                        //checking  compile jar
                        final String compileJarPath = compileJarTextField.getText();
                        if (compileJarPath == null || compileJarPath.length() < 1) {
                            checkingSuccess = false;
                            appendMessage("ERROR - compiler.jar is required, please choose jar file");
                        } else {
                            File file = new File(compileJarPath);
                            if (!file.exists()) {
                                checkingSuccess = false;
                                appendMessage("ERROR - compiler.jar: " + compileJarPath + " is not exist");
                            }
                        }
                        //checking compile path
                        final String compileJsPath = fileTextField.getText();
                        if (compileJsPath == null || compileJsPath.length() < 1) {
                            checkingSuccess = false;
                            appendMessage("ERROR - JS file is required, please choose js file");
                        } else {
                            File file = new File(compileJsPath);
                            if (!file.exists()) {
                                checkingSuccess = false;
                                appendMessage("ERROR - JS file: " + compileJsPath + " is not exist");
                            }
                        }
                        //checking compiled path
                        final String compiledJsPath = compiledTextField.getText();
                        if (compiledJsPath == null || compiledJsPath.length() < 1) {
                            checkingSuccess = false;
                            appendMessage("ERROR - Compiled path is empty");
                        }

                        if (checkingSuccess) {
                            executeBtn.setEnabled(false);
                            String command = "java -jar " + compileJarPath + " --js " + compileJsPath + " --js_output_file " + compiledJsPath;
                            appendMessage("Execute compile command: " + command);
                            try {
                                final Process process = Runtime.getRuntime().exec(command);
                                appendMessage("Compiling...");


                                final InputStream is = process.getErrorStream();
                                BufferedReader br = new BufferedReader(new InputStreamReader(is));
                                String message;
                                while ((message = br.readLine()) != null) {
                                    appendMessage(message);
                                }
                                appendMessage("Finish compile.");

                                //save values
                                PreferencesUtil.setCompilerJarPath(compileJarPath);
                                PreferencesUtil.setCompiledJSPath(compiledJsPath);
                                PreferencesUtil.setCompileJSPath(compileJsPath);

                            } catch (IOException e1) {
                                appendMessage("ERROR - execute failed: " + e1);
                            }

                        }
                        executeBtn.setEnabled(true);
                    }
                });
            }
        });
    }

    // java -jar compiler.jar --js name.js --js_output_file name2.js
    private void initialComponents() {
        this.mainJFrame = this;
        /*
        * center
        * */
        JPanel panel = new JPanel();
        panel.setLayout(new FlowLayout(FlowLayout.LEFT));
        panel.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY));


        JLabel label = new JLabel("compiler.jar:");
        panel.add(label);
        this.compileJarTextField = new JTextField(55);
        this.compileJarTextField.setEditable(false);
        panel.add(this.compileJarTextField);

        this.jarFileChooser = new JFileChooser();
        this.jarFileChooser.addChoosableFileFilter(new FileNameExtensionFilter("Jar file", "jar"));

        JButton button = new JButton("Choose Jar");
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                final int i = jarFileChooser.showOpenDialog(mainJFrame);
                if (JFileChooser.OPEN_DIALOG == i) {
                    final File selectedFile = jarFileChooser.getSelectedFile();
                    final String absolutePath = selectedFile.getAbsolutePath();
                    if (selectedFile.getName().endsWith("jar")) {
                        compileJarTextField.setText(absolutePath);
                        appendMessage("compiler.jar: " + absolutePath);
                    } else {
                        appendMessage("ERROR - compiler.jar: " + absolutePath + " is not jar file(.jar)");
                    }
                }
            }
        });
        panel.add(button);

        label = new JLabel("JS file path:");
        panel.add(label);
        this.fileTextField = new JTextField(55);
//        this.fileTextField.setEditable(false);
        panel.add(this.fileTextField);

        this.fileChooser = new JFileChooser();
        fileChooser.addChoosableFileFilter(new FileNameExtensionFilter("JS file", "js"));

        JButton openFileBtn = new JButton("Choose JS");
        openFileBtn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                final int i = fileChooser.showOpenDialog(mainJFrame);
                if (JFileChooser.OPEN_DIALOG == i) {
                    final File selectedFile = fileChooser.getSelectedFile();
                    final String absolutePath = selectedFile.getAbsolutePath();

                    if (selectedFile.getName().endsWith("js")) {
                        fileTextField.setText(absolutePath);

                        final String[] strings = selectedFile.getName().split("\\.");
                        String compiledFileName = strings[0] + ".min.js";
                        File compiledFile = new File(selectedFile.getParentFile(), compiledFileName);
                        final String compiledFullPath = compiledFile.getAbsolutePath();
                        compiledTextField.setText(compiledFullPath);
                        appendMessage("JS file path: " + absolutePath);
                        appendMessage("Compiled path: " + compiledFullPath);
                    } else {
                        appendMessage("ERROR - JS file path: " + absolutePath + " is not js file(.js)");
                    }
                }
            }
        });
        panel.add(openFileBtn);


        label = new JLabel("compiled path:");
        label.setForeground(Color.BLUE);
        panel.add(label);
        this.compiledTextField = new JTextField(54);
        panel.add(this.compiledTextField);

        this.messageTextArea = new JTextArea(9, 75);
        this.messageTextArea.setForeground(Color.BLACK);
        this.messageTextArea.setWrapStyleWord(true);
//        this.messageTextArea.setLineWrap(true);
//        this.messageTextArea.setToolTipText("Output message");
        this.messageTextArea.setEditable(false);

        JScrollPane scrollPane = new JScrollPane(this.messageTextArea);
        panel.add(scrollPane);

        JTextField field = new JTextField(" Create by: andaily.com (shengzhao@andaily.com) ");
        field.setEditable(false);
        field.setBackground(Color.LIGHT_GRAY);
        panel.add(field);

        button = new JButton("Clean");
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                messageTextArea.setText("");
            }
        });
        panel.add(button);

        this.executeBtn = new JButton("Execute");
        this.executeBtn.setForeground(Color.RED);
        this.executeBtn.setPreferredSize(new Dimension(150, 35));
        panel.add(this.executeBtn);

        this.add(panel, BorderLayout.CENTER);

    }


    private void appendMessage(String text) {
        final String time = dateFormat.format(new Date());
        messageTextArea.append(time + " " + text + "\n");
    }

    private void showMe() {
        this.setTitle("closure-compiler-gui");
        this.setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
        Point p = SwingUtil.getStartPoint(this.getWidth(), this.getHeight());
        this.setLocation(p);

        this.setResizable(false);
        this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        this.setVisible(true);
    }


    private JFileChooser fileChooser;
    private JFileChooser jarFileChooser;
    private JButton executeBtn;

    private JTextArea messageTextArea;
    private JTextField compiledTextField;
    private JTextField compileJarTextField;

    private JTextField fileTextField;
    private MainJFrame mainJFrame;

    private SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");

    public static final int DEFAULT_WIDTH = 550;
    public static final int DEFAULT_HEIGHT = 350;


}